package org.vacoor.nothing.misc.rmc.support.http;

import com.google.common.base.Charsets;
import org.vacoor.nothing.common.reflect.Parameter;
import org.vacoor.nothing.common.util.HttpUtils;
import org.vacoor.nothing.common.util.IOUtils;
import org.vacoor.nothing.common.util.StringUtils;
import org.vacoor.nothing.misc.rmc.binding.MapperMethod;
import org.vacoor.nothing.misc.rmc.session.Session;
import org.vacoor.nothing.misc.rmc.support.http.annotation.RequestMapping;
import org.vacoor.nothing.misc.rmc.support.http.annotation.RequestParam;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 */
public class HttpMapperMethod extends MapperMethod {

    public HttpMapperMethod(Class mapperInterface, Method method, Session session) {
        super(mapperInterface, method, session);
    }

    @Override
    public Object execute(Object[] args) throws Throwable {
        Class<?> retType = method.getReturnType();
        InputStream is = doRequest(method, args);

        if (InputStream.class == retType) {
            return is;
        }

        if (byte[].class == retType) {
            return IOUtils.readBytes(is, true);
        }

        if (String.class == retType) {
            return IOUtils.readText(is, Charsets.UTF_8, true);
        }
        return is;
    }

    protected InputStream doRequest(final Method method, final Object[] args) {
        final Class<?> clazz = method.getDeclaringClass();
        Parameter[] parameters = Parameter.lookup(method);

        RequestMapping local = clazz.getAnnotation(RequestMapping.class);
        RequestMapping request = method.getAnnotation(RequestMapping.class);

        String url = "";
        String m = "";
        Map<String, String> params = new HashMap<String, String>();

        if (null == local && null == request) {
//            throw new
        }

        if (null != local) {
            url = local.value();
            m = local.method();
            String[] kvs = local.extraParams();
            String[] headers = local.headers();

            for (String kv : kvs) {
                if(!StringUtils.hasText(kv)) {
                    continue;
                }
                int i = kv.indexOf("=");
                String name = 0 > i ? kv : kv.substring(0, i);
                String value = 0 > i ? "" : kv.substring(i + 1);
                params.put(name, value);
            }
        }

        if (null != request) {
            String mUrl = request.value();
            String[] strings = request.extraParams();

            if (null == url || mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
                url = mUrl;
            } else if (StringUtils.hasText(mUrl)){
                url += mUrl.startsWith("/") ? mUrl : "/" + mUrl;
            }

            for (String kv : strings) {
                if(!StringUtils.hasText(kv)) {
                    continue;
                }
                int i = kv.indexOf("=");
                String name = 0 > i ? kv : kv.substring(0, i);
                String value = 0 > i ? "" : kv.substring(i + 1);
                params.put(name, value);
            }
        }

        for (Parameter parameter : parameters) {
            RequestParam anno = parameter.getAnnotation(RequestParam.class);
            if (null != anno) {
                params.put(anno.value(), args[parameter.getIndex()].toString());
            }
        }

        System.out.println(url);
        System.out.println(params);

        return HttpUtils.get(url, params, 3* 1000);
    }
}
